解决浏览器回退表单重复提交问题

暂时没有别的什么好办法,在网上搜索到用sessionStorage+ajax形式请求数据来避免浏览器回退表单重复提交.

首先页面展示为订单列表,分为三个tab,为未支付订单,已支付订单,过期订单,在列表里点击一个item时进入订单详情页,回退后要求效果为还停留在原来的tab,列表位置也要在选中位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  <div class="mainBody" style="height: auto">
<div class="mainBodyBack">
<div class="orderSelection">
<div class="orderSelectionTags">
<div id="waitPayId" class="orderButtonInsurance orderButtonInsuranceBack">待支付
<div class="underLine show"></div>
</div>
<div id="hasPayId" class="orderButtonInsurance">已支付
<div class="underLine"></div>
</div>
<div id="overdateId" class="orderButtonInsurance">已过期
<div class="underLine"></div>
</div>
</div>
</div>

<%--待支付--%>
<div class="orderListBack show" id="orderWaitPay">
</div>

<%--已支付--%>
<div class="orderListBack" id="orderHasPay">
</div>

<%--已过期--%>
<div class="orderListBack" id="orderoverDate">
</div>
</div>
</div>

原来的实现方式时直接在waitPayId,hasPayId,overdateId三个div中填充数据,现在要修改为用ajax请求的方式进行填充。

ajax请求的部分代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
function getOrderListData() {
dismissAlertAction()
$.ajax({
url: "${ctx}/order/getOrderList",
type: "POST",
data: {},
dataType: "json",
success: function (resp) {
if (resp.code === 0) {
console.info(resp.data)
//未支付订单列表
var listUnPaidOrder = new Array();
listUnPaidOrder = resp.data[0];
//已只读订单列表
var listPaidOrder = new Array();
listPaidOrder = resp.data[1];
//过期订单列表
var listOverDateOrder = new Array();
listOverDateOrder = resp.data[2];
console.info(listUnPaidOrder.length)
console.info(listPaidOrder.length)
console.info(listOverDateOrder.length)

window.sessionStorage.setItem("listUnPaidOrder", JSON.stringify(listUnPaidOrder));
window.sessionStorage.setItem("listPaidOrder", JSON.stringify(listPaidOrder));
window.sessionStorage.setItem("listOverDateOrder", JSON.stringify(listOverDateOrder));

fillDataView(listUnPaidOrder, listPaidOrder, listOverDateOrder);
}
}
});
}

页面加载自动调用的js代码为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//当前切换的tab值
var titleTab = window.sessionStorage.getItem("titleTab");
if (titleTab == null || titleTab == "") {
titleTab = 0;
}
var currentTab = titleTab;

function setHeight() {
$("html,body").css("height","100%");
}
function fillDataView(listUnPaidOrder, listPaidOrder, listOverDateOrder) {
var divUnPaidOrder = "";
//未支付订单列表
if (listUnPaidOrder.length == 0) {
setHeight()
divUnPaidOrder += '<div class="orderNoneBack" id="orderWaitPay"> <div class="orderListEmpty"> <img src="${ctx}/resources/img/noOrder.png" alt=""/> <div class="orderListEmptyText">您还没有相关订单记录</div> </div> </div>';
} else {
for (var i = 0; i < listUnPaidOrder.length; i++) {
var orderDto = listUnPaidOrder[i];
divUnPaidOrder += ' <div class="orderClass"> <div class="orderClassHeader">' +
' <div class="orderClassDate">' + orderDto.createOrderTime + '</div>' +
' <div class="orderDetailButton" onclick="goToOrderDetail(' + orderDto.id + ')">查看详情 </div> ' +
'</div> <div class="orderInformation"> <div class="orderImg"> <div class="orderHeadImg insurance_' + orderDto.insuCom + '"> </div> ' +
'</div> <div class="orderInsurance"> <div class="orderInsurnceText">' + orderDto.insuComName + '</div> ' +
'<div class="orderInsurnceText lightColor">共投保 ' + orderDto.coverageCount + '种保险</div> ' +
'</div> <div class="orderBuyer"> <div class="orderInsurnceText">' + orderDto.licenseNo + '</div> ' +
'<div class="orderInsurnceText">' + orderDto.insuredName + '</div> </div> </div> <div class="orderFooter">' +
' <div class="left-apart">实付款:<span class="moneyColor">' + (orderDto.sumAmount / 100).toFixed(2) + '元</span>' +
' </div> <div class="right-apart" ' +
'onclick="payAtOnece('+orderDto.id+')">立即支付 </div> </div> </div>';
}
}
$("#orderWaitPay").html(divUnPaidOrder);
var divPaidOrder = "";
//已支付订单列表
if (listPaidOrder.length == 0) {
setHeight()
divPaidOrder = '<div class="orderNoneBack" id="orderWaitPay"> <div class="orderListEmpty"> <img src="${ctx}/resources/img/noOrder.png" alt=""/> <div class="orderListEmptyText">您还没有相关订单记录</div> </div> </div>';
} else {
for (var i = 0; i < listPaidOrder.length; i++) {
var orderPaidDto = listPaidOrder[i];
divPaidOrder += '<div class="orderClass"> <div class="orderClassHeader"> ' +
'<div class="orderClassDate">'
+ orderPaidDto.createOrderTime +
'</div>' +
' <div class="orderDetailButton" ' +
'onclick=" goToOrderDetail(' + orderPaidDto.id + ')">' +
'查看详情 ' +
'</div> </div>' +
' <div class="orderInformation">' +
' <div class="orderImg"> ' +
'<div class="orderHeadImg insurance_' + orderPaidDto.insuCom + '">' +
' </div> </div> ' +
'<div class="orderInsurance"> ' +
'<div class="orderInsurnceText">' +
orderPaidDto.insuComName +
'</div> ' +
'<div class="orderInsurnceText lightColor">' +
'共投保' + orderPaidDto.coverageCount + '种保险</div>' +
' </div> <div class="orderBuyer">' +
' <div class="orderInsurnceText">' +
orderPaidDto.licenseNo +
'</div> <div class="orderInsurnceText">'
+ orderPaidDto.insuredName +
'</div> </div> ' +
'</div> <div class="orderFooter">实付款:<span class="moneyColor">'
+ (orderPaidDto.sumAmount / 100).toFixed(2) + '元</span> ' +
'</div> </div>';
}
}
$("#orderHasPay").html(divPaidOrder);

var divOverDateOrder = "";
//已过期订单列表
if (listOverDateOrder.length == 0) {
setHeight()
divOverDateOrder = '<div class="orderNoneBack" id="orderWaitPay"> <div class="orderListEmpty"> <img src="${ctx}/resources/img/noOrder.png" alt=""/> <div class="orderListEmptyText">您还没有相关订单记录</div> </div> </div>';
} else {
for (var i = 0; i < listOverDateOrder.length; i++) {
var orderOverDateDto = listOverDateOrder[i];
divOverDateOrder += ' <div class="orderClass"> <div class="orderClassHeader">' +
' <div class="orderClassDate">' + orderOverDateDto.createOrderTime + '</div> ' +
'<div class="orderDetailButton" onclick="goToOrderDetail(' + orderOverDateDto.id + ')">查看详情 </div>' +
' </div> <div class="orderInformation"> <div class="orderImg"> <div class="orderHeadImg insurance_' + orderOverDateDto.insuCom + '"> </div> ' +
'</div> <div class="orderInsurance"> <div class="orderInsurnceText">' + orderOverDateDto.insuComName + '</div> <div class="orderInsurnceText lightColor">' +
'共投保' + orderOverDateDto.coverageCount + '种保险</div> </div> <div class="orderBuyer"> ' +
'<div class="orderInsurnceText">' + orderOverDateDto.licenseNo + '</div> ' +
'<div class="orderInsurnceText">' + orderOverDateDto.insuredName + '</div> </div>' +
' </div> <div class="orderFooter"> <div class="left-apart">实付款:<span class="moneyColor">' + (orderOverDateDto.sumAmount / 100).toFixed(2) + '元</span>' +
' </div> <div class="right-apart"' +
'onclick=" reQuotePrice(' + orderOverDateDto.id + ')">重新报价 </div>' +
' <div class="right-apart margin-right-jt"' +
' onclick=" cancelOrder(' + orderOverDateDto.id + ')">删除订单 </div> </div> </div>';
}
}
$("#orderoverDate").html(divOverDateOrder);
}

大概就是浏览器回退再次调用ajax请求的时候判断是否已经调用过,标记保存在sessionStorage里面,这里说下sessionStorage,了解到sessionStorage用于存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。所以sessionStorage不是一种持久化的本地存储,仅仅是会话级存储方式。
而localStorage用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。

Web Storage的概念和cookie相似,区别是它是为了更大容量存储设计的。Cookie的大小是受限的,并且每次你请求一个新的页面的时候Cookie都会被发送过去,这样无形中浪费了带宽,另外cookie还需要指定作用域,不可以跨域调用。

除此之外,Web Storage拥有setItem,getItem,removeItem,clear等方法,不像cookie需要前端开发者自己封装setCookie,getCookie。

但是Cookie也是不可以或缺的:Cookie的作用是与服务器进行交互,作为HTTP规范的一部分而存在 ,而Web Storage仅仅是为了在本地“存储”数据而生。

localStorage和sessionStorage都具有相同的操作方法,例如setItem、getItem,removeItem,clear等.

之前的做法是把这个标志位存储到服务器端,比如存入redis在记录,但是比较来说存储到redis的形势不仅对服务器压力大,而且会影响到业务逻辑实现等等,这样单页面session会话级别存储更清晰一些。